/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package afterubuntu.script;

import afterubuntu.log.Log;
import afterubuntu.pojo.APTPackage;
import afterubuntu.pojo.AfterUbuntuData;
import afterubuntu.pojo.Application;
import afterubuntu.pojo.AutConfiguration;
import afterubuntu.pojo.Category;
import afterubuntu.pojo.CmdConfiguration;
import afterubuntu.pojo.DEBPackage;
import afterubuntu.pojo.GPARepository;
import afterubuntu.pojo.GetConfiguration;
import afterubuntu.pojo.IcoConfiguration;
import afterubuntu.pojo.PPARepository;
import afterubuntu.pojo.REMPackage;
import afterubuntu.pojo.RepositoryKey;
import afterubuntu.pojo.ZipConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Kermit
 */
public class GenerateScript implements Runnable{

    public static final int ERROR = -1;
    public static final int OK = 0;
    public static final int ACCESS_DENIED = 1;
    
    private AfterUbuntuData afterUbuntuData;
    
    private GenerateScriptListener generateScriptListener;
    private String script;
    
    public GenerateScript(AfterUbuntuData afterUbuntuData){
        this.afterUbuntuData = afterUbuntuData;
        this.generateScriptListener = null;
    }
    
    public void addGenerateScriptListener(GenerateScriptListener generateScriptListener){
        this.generateScriptListener = generateScriptListener;
    }

    public void run() {

        HashMap<String, Category> categories = afterUbuntuData.getCategories();
        Set<String> categoriesKeys = categories.keySet();

        script = "#!/bin/bash\n\n";

        script += "echo \"AfterUbuntu script\"\n\n";

        script += "sudo chmod a+w /opt\n";
        script += "sudo chmod g+w /opt\n";
        
        script += "echo \"Step 1: Repositories\"\n\n";
        
        script += "echo \"Step 1.1: Adding generic repositories\"\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<GPARepository> gpaRepositories = application.getGPARepositories();
                        for(GPARepository gpaRepository : gpaRepositories){
                            script += "noEcho=$(echo " + gpaRepository.getRepository() + " | sudo tee /etc/apt/sources.list.d/" + gpaRepository.getName() + ".list)\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 1.2: Adding PPA repositories\"\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<PPARepository> ppaRepositories = application.getPPARepositories();
                        for(PPARepository ppaRepository : ppaRepositories){
                            script += "sudo add-apt-repository ppa:" + ppaRepository.getRepository() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 1.3: Adding repository keys\"\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<RepositoryKey> repositoryKeys = application.getRepositoryKeys();
                        for(RepositoryKey repositoryKey : repositoryKeys){
                            script += "wget -q " + repositoryKey.getKey() + " -O- | sudo apt-key add -\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 1.4: Updating repositories\"\n\n";

        script += "sudo apt-get update;\n";
        script += "IFS=$'\n'";
        script += "for line in `sudo apt-get update 2>&1|grep NO_PUBKEY|awk 'FS=\" \" {print \"sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com \" $NF}'`; do\n";
        script += "\techo $line |sh\n";
        script += "done\n";
        script += "sudo apt-get -y --force-yes upgrade;\n";
        script += "sudo apt-get -y --force-yes dist-upgrade\n";

        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 2: Software\"\n\n";

        script += "echo \"Step 2.1: Installing packages from repositories\"\n\n";

        boolean aptSetGet = false;
        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        if(!aptSetGet){
                            script += "sudo apt-get -y --force-yes install ";
                            aptSetGet = true;
                        }
                        ArrayList<APTPackage> aptPackages = application.getAPTPackages();
                        for(APTPackage aptPackage : aptPackages){
                            ArrayList<String> aptPackagesStr = aptPackage.getAPTPackages();
                            for(String aptPackageStr : aptPackagesStr){
                                script += aptPackageStr + " ";
                            }
                        }
                    }
                }
            }
        }
        script += "\n";
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 2.2: Installing deb packages\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<DEBPackage> debPackages = application.getDEBPackages();
                        for(DEBPackage debPackage : debPackages){
                            ArrayList<String> debPackagesStr = debPackage.getDEBPackages();
                            for(String debPackageStr : debPackagesStr){
                                String[] split = debPackageStr.split(" ");
                                for(int i = 0; i<split.length; i++){
                                    script += "wget -m -r -t 5 -nd -P /tmp " + split[i] + "\n";
                                }
                                script += "sudo dpkg -i ";
                                for(int i = 0; i<split.length; i++){
                                    script += "/tmp" + split[i].substring(split[i].lastIndexOf("/"), split[i].length()) + " ";
                                }
                                script += "\n";
                            }
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 2.3: Removing packages\"\n\n";

        boolean aptSetRem = false;
        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        if(!aptSetRem){
                            script += "sudo apt-get purge ";
                            aptSetRem = true;
                        }
                        ArrayList<REMPackage> remPackages = application.getREMPackages();
                        for(REMPackage remPackage : remPackages){
                            ArrayList<String> remPackagesStr = remPackage.getREMPackages();
                            for(String remPackageStr : remPackagesStr){
                                script += remPackageStr + " ";
                            }
                        }
                    }
                }
            }
        }
        script += "\n";
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 2.4: Finalizing software installation\"\n\n";
        if(aptSetGet){
            script += "sudo apt-get clean\n";
        }
        if(aptSetRem){
            script += "sudo apt-get autoremove\n";
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 3: Software configuration\"\n\n";

        script += "echo \"Step 3.1: Downloading files\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<GetConfiguration> getPackages = application.getGetConfigurations();
                        for(GetConfiguration getPackage : getPackages){
                            script += "wget -m -r -t 5 -nd -P " + getPackage.getDirectory() + " " + getPackage.getUrl() +"\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 3.2: Downloading and unzipping files\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<ZipConfiguration> zipPackages = application.getZipConfigurations();
                        for(ZipConfiguration zipPackage : zipPackages){
                            script += "wget -m -r -t 5 -nd -P /tmp " + zipPackage.getZipFile() + "\n";
                            script += "unzip /tmp" + zipPackage.getZipFile().substring(zipPackage.getZipFile().lastIndexOf("/")) + " -d " + zipPackage.getDirectory() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 3.3: Downloading icons\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<IcoConfiguration> icoPackages = application.getIcoConfigurations();
                        for(IcoConfiguration icoPackage : icoPackages){
                            script += "sudo wget -m -r -t 5 -nd -P /usr/share/applications " + icoPackage.getUrl() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 3.4: Downloading autoexecute launcher\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<AutConfiguration> autPackages = application.getAutConfigurations();
                        for(AutConfiguration autPackage : autPackages){
                            script += "wget -m -r -t 5 -nd -P $HOME/.config/autostart " + autPackage.getUrl() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 3.5: Executing commands\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<CmdConfiguration> cmdPackages = application.getCmdConfigurations();
                        for(CmdConfiguration cmdPackage : cmdPackages){
                            script += cmdPackage.getCommand() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 4: User configuration\"\n\n";

        script += "echo \"Step 4.1: Downloading files\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<GetConfiguration> getPackages = application.getGetUser();
                        for(GetConfiguration getPackage : getPackages){
                            script += "wget -m -r -t 5 -nd -P " + getPackage.getDirectory() + " " + getPackage.getUrl() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 4.2: Downloading and unzipping files\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<ZipConfiguration> zipPackages = application.getZipUser();
                        for(ZipConfiguration zipPackage : zipPackages){
                            script += "wget -m -r -t 5 -nd -P /tmp " + zipPackage.getZipFile() + "\n";
                            script += "unzip /tmp" + zipPackage.getZipFile().substring(zipPackage.getZipFile().lastIndexOf("/")) + " -d " + zipPackage.getDirectory() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 4.3: Downloading icons\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<IcoConfiguration> icoPackages = application.getIcoUser();
                        for(IcoConfiguration icoPackage : icoPackages){
                            script += "sudo wget -m -r -t 5 -nd -P /usr/share/applications " + icoPackage.getUrl() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 4.4: Downloading autoexecute launcher\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<AutConfiguration> autPackages = application.getAutUser();
                        for(AutConfiguration autPackage : autPackages){
                            script += "wget -m -r -t 5 -nd -P $HOME/.config/autostart " + autPackage.getUrl() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to continue... \" -n 1";

        script += "echo \"Step 4.5: Executing commands\"\n\n";

        for(String categoryKey : categoriesKeys){
            if(categories != null){
                Category category = categories.get(categoryKey);
                HashMap<String, Application> applications = category.getApplications();
                Set<String> applicationsKeys = applications.keySet();
                for(String applicationKey : applicationsKeys){
                    Application application = applications.get(applicationKey);
                    if(application.getInstall()){
                        ArrayList<CmdConfiguration> cmdPackages = application.getCmdUser();
                        for(CmdConfiguration cmdPackage : cmdPackages){
                            script += cmdPackage.getCommand() + "\n";
                        }
                    }
                }
            }
        }
        script += "echo \"Done\"\n\n";

        //script += "read -p \"Press a key to exit... \" -n 1";

        script += "exit 0\n";
        if(generateScriptListener != null) generateScriptListener.generationProcessFinished(GenerateScript.OK);
    }

    public int saveScript(File file) {
        int result;
        PrintWriter fileWriter = null;
        try {
            fileWriter = new PrintWriter(file);
            fileWriter.write(script);
            fileWriter.flush();
            result = GenerateScript.OK;
            //if(generateScriptListener != null) generateScriptListener.savingProcessFinished(GenerateScript.OK);
        } catch (IOException ex) {
            result = GenerateScript.ERROR;
            //if(generateScriptListener != null) generateScriptListener.savingProcessFinished(GenerateScript.ACCESS_DENIED);
            Log.getInstance().log(Log.ERROR, ex.getLocalizedMessage());
        } finally {
           // try {
                if(fileWriter != null) fileWriter.close();
            /*} catch (IOException ex) {
                if(generateScriptListener != null) generateScriptListener.savingProcessFinished(GenerateScript.ERROR);
                Log.getInstance().log(Log.ERROR, ex.getLocalizedMessage());
            }*/
        }
        try {
            Process chmod = Runtime.getRuntime().exec("chmod +x " + file.getAbsolutePath());
            int resultAux = chmod.waitFor();
            if(resultAux != 0){
                result = GenerateScript.ERROR;
            }else{
                result = GenerateScript.OK;
            }
        } catch (IOException ex) {
            result = GenerateScript.ERROR;
            Logger.getLogger(GenerateScript.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ie){
            result = GenerateScript.ERROR;
            Logger.getLogger(GenerateScript.class.getName()).log(Level.SEVERE, null, ie);
        }

        return result;
    }

}
